﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using System.IO;
using System.IO.IsolatedStorage;
using System.Collections;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Services;
using MainGame.SaveData;
using System.Diagnostics;

namespace MainGame.Menu
{

  public interface IProfileMenu
  {
    event MenuEvent OnNewProfileClicked;
    event MenuEvent OnBackClicked;
    event MenuEvent OnReload;

  }


  public class ProfileMenu : BaseMenu, IProfileMenu
  {
    Button[] SavedProfile;
    Button newProfile, BackToMM, Delete, Load, Confirm, Decline, DeleteAll, LeftControlPanel, RightControlPanel;
    Button PanelBox, ShadowBox, BestScore, GamesPlayed, GamesWon, PlayedTime, square, Black;
    List<string> UserNames, Profiles;
    public bool Animated = false, flag = false, OnDelete = false, ErrDel = false;
    public int Direction = 1, MaxProfCount = 0, clickedBtn = -1;
    Vector2 savedPos;
    Texture2D RoundedBox;
    Color colorBox, colorBoxShadow, ColorProfile, ColorTimer;
    bool OverloadProfile = false;
    Profile selectedProfile;
    string str;

    SpriteBatch spriteBatch;

    public ProfileMenu(Game game, MenuDepths depth)
      : base(game, depth)
    {
      spriteBatch = Game.GetContext().SpriteBatch;
      background = game.Content.Load<Texture2D>(@"Images//Backgrounds//Bg_Squares");
      bounds = new Rectangle(0, -game.GraphicsDevice.Viewport.Height, 800, 480);
      game.Services.AddService(typeof(IProfileMenu), this);
    }

    protected override void Dispose(bool disposing)
    {
      Game.Services.RemoveService(typeof(IProfileMenu));
      base.Dispose(disposing);
    }


    public override void Initialize()
    {
      Profiles = SaveUtils.GetProfileList(Game);
      UserNames = SaveUtils.GetUsernameList(Game);
      SavedProfile = new Button[UserNames.Count];
      RoundedBox = Game.Content.Load<Texture2D>(@"Images//Game//roundedBox");
      colorBox = new Color(29, 194, 192, 200);
      colorBoxShadow = new Color(0, 0, 0, 100);
      ColorProfile = new Color(47, 52, 228, 200);
      ColorTimer = new Color(0, 0, 0, 230);
      selectedProfile = Game.LoadProfileByString("Profile0.car");


      int PosY = 100, PosX = 0;
            

      RightControlPanel = new Button(Game, @"Images//Game//roundedBox", new Rectangle(495, bounds.Y + 65, 300, 310), ColorProfile, "baveuse1_font", Locale.Strings.No, Color.Transparent);
      AddButton(RightControlPanel, () =>
      { });

      LeftControlPanel = new Button(Game, @"Images//Game//roundedBox", new Rectangle(5, bounds.Y + 65, 485, 310), ColorProfile, "baveuse1_font", Locale.Strings.No, Color.Transparent);
      AddButton(LeftControlPanel, () =>
      { });

      square = new Button(Game, @"Images//Game//roundedBox", new Rectangle(495, bounds.Y + 65, 300, 310), Color.Transparent, "baveuse1_font", "", Color.Transparent);
      AddButton(square, () =>
      { });

      for (int i = 0; i < UserNames.Count; i++)
      {
        var curr_i = i;
        PosX = i;
        if (PosX > 2)
        {
          PosY = 200;
        
          if (i > 5)
            PosY = 300;
          
          PosX = PosX % 3;
          
        }

        SavedProfile[i] = new Button(Game, @"Images//Menu//button2", new Rectangle(-145 + ((PosX + 1) * 160), (int)bounds.Y + PosY, 140, 45), Color.Green, "baveuse1_font", UserNames[i], Color.Black, 0.6f);
        AddButton(SavedProfile[i], () =>
        {
          if ((ErrDel) || (OverloadProfile) || (Confirm.color == Color.Transparent))
          {
            var context = Game.GetContext();

            selectedProfile = Game.LoadProfileByString(Profiles[curr_i]);
            //BestScore.message = Locale.Strings.BestScore.Replace("\\n", "\n") + selectedProfile.bestScore.ToString();
            GamesPlayed.message = Locale.Strings.GamesPlayed + selectedProfile.gamesPlayed.ToString();
            GamesWon.message = Locale.Strings.GamesWon + selectedProfile.gamesWon.ToString();

            TimeSpan elapsedTimeSpan = TimeSpan.FromSeconds((double)selectedProfile.timePlayed);
            string printedTime = elapsedTimeSpan.Minutes + ":" + elapsedTimeSpan.Seconds;
            if (elapsedTimeSpan.Minutes < 10)
              printedTime = printedTime.Insert(0, "0");
            if (elapsedTimeSpan.Seconds < 10)
              printedTime = printedTime.Insert(printedTime.Length - 1, "0");
            PlayedTime.message = Locale.Strings.TimePlayed.Replace("\\n", "\n") + elapsedTimeSpan.Hours + ":" + printedTime;

            //hilights the selected button
            if ((curr_i != clickedBtn) && (clickedBtn != -1))
            {
              SavedProfile[clickedBtn].bounds.X += 5;
              SavedProfile[clickedBtn].bounds.Y += 5;
              clickedBtn = curr_i;
              SavedProfile[curr_i].bounds.X -= 5;
              SavedProfile[curr_i].bounds.Y -= 5;
            }
            else if (clickedBtn != curr_i)
            {
              clickedBtn = curr_i;
              SavedProfile[curr_i].bounds.X -= 5;
              SavedProfile[curr_i].bounds.Y -= 5;
            }
            
            //When a button is selected appear a shape under the button
            square.color = new Color(0,0,0, 150);
            square.bounds = new Rectangle(SavedProfile[curr_i].bounds.X + 5, SavedProfile[curr_i].bounds.Y + 5, SavedProfile[curr_i].bounds.Width , SavedProfile[curr_i].bounds.Height );
            

            var soundManager = Game.Services.GetService(typeof(GameSound.ISoundManager<GameSound.MenuSounds>)) as GameSound.ISoundManager<GameSound.MenuSounds>;
            if (soundManager != null)
            {
              soundManager.MusicMuted = context.currentConfig.musicMuted;
              soundManager.SfxMuted = context.currentConfig.sfxMuted;
              if (context.currentConfig.musicMuted)
                soundManager.StopMusic();
            }
          }
        });
      }

      savedPos.Y = bounds.Y;

      newProfile = new Button(Game, @"Images//Menu//button2", new Rectangle(520, (int)bounds.Y + 400, 240, 45), Color.Blue, "large_font", Locale.Strings.NewProfile, Color.White, 0.8f);
      AddButton(newProfile, () =>
      {
        newProfile.touched = true;        
      });

      BackToMM = new Button(Game, @"Images//Menu//button2", new Rectangle(30, (int)bounds.Y + 400, 140, 45), Color.PaleGreen, "large_font", Locale.Strings.Back, Color.Blue, 0.8f);
      AddButton(BackToMM, () =>
      {
        BackToMM.touched = true;
        
      });

      Load = new Button(Game, @"Images//Menu//button2", new Rectangle(bounds.Center.X + 110, bounds.Y + 270, 120, 75), Color.Green, "baveuse_small", Locale.Strings.Load, Color.White);
       AddButton(Load, () =>
       {
         Load.touched = true;
         if ((clickedBtn != -1) && (!OnDelete) && (Confirm.color == Color.Transparent) && (!OverloadProfile))
         {
           // Save the configuration for the current user
           var context = Game.GetContext();
           //Game.SaveConfig(context.currentConfig, context.currentProfile.id);
           // Load the new user profile and configuration
           Profile profile = Game.LoadProfileByString(Profiles[clickedBtn]);
           //context.currentProfile = profile;
           //context.currentConfig = Game.LoadConfig(context.currentProfile.id);

           Direction = -1;
           Animated = true;
         }
       
       });

      Delete = new Button(Game, @"Images//Menu//button2", new Rectangle(bounds.Center.X + 240, bounds.Y + 270, 120, 75), Color.Red, "baveuse_small", Locale.Strings.DeleteProfile.Replace("\\n", "\n"), Color.White);
      AddButton(Delete, () =>
      {
        Delete.touched = true;
        if (Profiles.Count < 1)
        {
          ErrDel = true;
          Black.color = ColorTimer;
        }
        else if((clickedBtn != -1) && (!OnDelete) && (Confirm.color == Color.Transparent) && (!OverloadProfile))
        {
          OnDelete = true;
          Confirm.color = Color.MediumBlue;
          Confirm.textColor = Color.White;
          Decline.color = Color.Red;
          Decline.textColor = Color.White;
          PanelBox.color = colorBox;
          ShadowBox.color = colorBoxShadow;
          Black.color = ColorTimer;
        }
        
      });

      DeleteAll = new Button(Game, @"Images//Menu//button2", new Rectangle(240, (int)bounds.Y + 400, 205, 45), Color.Red, "large_font", Locale.Strings.DeleteAll, Color.White, 0.8f);
      AddButton(DeleteAll, () =>
      {
        DeleteAll.touched = true;

        if (Profiles.Count < 1)
        {
          ErrDel = true;
          Black.color = ColorTimer;
        }
        else if (!OverloadProfile)
        {
          Confirm.color = Color.MediumBlue;
          Confirm.textColor = Color.White;
          Decline.color = Color.Red;
          Decline.textColor = Color.White;
          PanelBox.color = colorBox;
          ShadowBox.color = colorBoxShadow;
          Black.color = ColorTimer;
        }
      });

      if(selectedProfile.id != 0)
        str = selectedProfile.username.ToString();      

      //BestScore = new Button(Game, @"white_pixel", new Rectangle(bounds.Center.X + 200, bounds.Y + 90, 80, 45), Color.Transparent, "baveuse1_font", "", Color.Yellow, 0.6f);
      //AddButton(BestScore, () => { });

      GamesPlayed = new Button(Game, @"white_pixel", new Rectangle(bounds.Center.X + 200, bounds.Y + 90, 80, 45), Color.Transparent, "baveuse1_font", "", Color.Yellow, 0.6f);
      AddButton(GamesPlayed, () => { });

      GamesWon = new Button(Game, @"white_pixel", new Rectangle(bounds.Center.X + 200, bounds.Y + 120, 80, 45), Color.Transparent, "baveuse1_font", "", Color.Yellow, 0.6f);
      AddButton(GamesWon, () => { });

      PlayedTime = new Button(Game, @"white_pixel", new Rectangle(bounds.Center.X + 200, bounds.Y + 160, 80, 45), Color.Transparent, "baveuse1_font", "", Color.Yellow, 0.6f);
      AddButton(PlayedTime, () => { });

      Black = new Button(Game, @"Images//Game//roundedBox", new Rectangle(bounds.X - 50, bounds.Y - 50, 900, 560), Color.Transparent, "baveuse_small", "", Color.Transparent);
      AddButton(Black, () => { });

      ShadowBox = new Button(Game, @"Images//Game//roundedBox", new Rectangle(bounds.X + 50, bounds.Y + 140, 740, 160), Color.Transparent, "baveuse_small", Locale.Strings.No, Color.Transparent);
      AddButton(ShadowBox, () => { });

      PanelBox = new Button(Game, @"Images//Game//roundedBox", new Rectangle(bounds.X + 40, bounds.Y + 130, 740, 160), Color.Transparent, "baveuse_small", Locale.Strings.No, Color.Transparent, 1.5f);
      AddButton(PanelBox, () => { });

      Confirm = new Button(Game, @"Images//Menu//button2", new Rectangle(PanelBox.bounds.Center.X - 190, (int)bounds.Y + 240, 80, 45), Color.Transparent, "baveuse1_font", Locale.Strings.Yes, Color.Transparent);
      AddButton(Confirm, () =>
      {
        if (OnDelete)
        {
          OnDelete = false;

          // Function that delete the profile associated to the button
          SaveUtils.DeleteUserByProfile(Profiles[clickedBtn]);

          // Check if the user deleted the current active profile
          string confrontStr = Profiles[clickedBtn].Substring(7).Trim('.', 'c', 'a', 'r');
          //if (Game.GetContext().currentProfile.id.ToString().Equals(confrontStr))
          //{
          //  // If so, set the current profile to the default profile
          //  Game.GetContext().currentProfile = Game.LoadProfile(0);
          //  Game.GetContext().currentConfig = Game.LoadConfig(0);
          //}

          if (OnReload != null)
            OnReload();

        }
        else if (Confirm.color != Color.Transparent)
        {
          // Delete all the profiles
          for (int i = 0; i < Profiles.Count; ++i)
            SaveUtils.DeleteUserByProfile(Profiles[i]);

          // Set the current profile to the default profile
          //Game.GetContext().currentProfile = Game.LoadProfile(0);
          Game.GetContext().currentConfig = Game.LoadConfig(0);

          if (OnReload != null)
            OnReload();
        }
      });

      Decline = new Button(Game, @"Images//Menu//button2", new Rectangle(PanelBox.bounds.Center.X + 100, (int)bounds.Y + 240, 80, 45), Color.Transparent, "baveuse1_font", Locale.Strings.No, Color.Transparent);
      AddButton(Decline, () =>
      {
        if (OnDelete)
          OnDelete = false;  

        Confirm.color = Color.Transparent;
        Confirm.textColor = Color.Transparent;
        Decline.color = Color.Transparent;
        Decline.textColor = Color.Transparent;
        PanelBox.color = Color.Transparent;
        PanelBox.textColor = Color.Transparent;
        ShadowBox.color = Color.Transparent;
        Black.color = Color.Transparent;
        counter = 4;

      });

      base.Initialize();
    }

    int counter = 4;

    public override void Update(GameTime gameTime)
    {
      // Back non puo essere premuto se c'e' un pannello attivo
      

        if (BackToMM.touched)
        {
          if ((ErrDel) || (OverloadProfile) || (Confirm.color != Color.Transparent))
            counter = 5;
          else
            counter--;
          
          if (counter <= 0)
            {
              Direction = -1;
              Animated = true;
            }
          } 
        

      if (newProfile.touched)
      {
        if ((ErrDel) || (OverloadProfile) || (Confirm.color != Color.Transparent))
          counter = 5;
        else
          counter--;

        counter--;
        if (counter < 0)
        {
          if (SavedProfile.Length > 8)
          {
            OverloadProfile = true;
            counter = 4;
          }
          else
          {
            Direction = -1;
            flag = true;
            Animated = true;
          }
        }
      }

      // Input: back button pressed
      if (((Game1)Game).IsBackButtonPressed())
      {

        if (Confirm.color != Color.Transparent)
        {
          if (OnDelete)
            OnDelete = false;

          Confirm.color = Color.Transparent;
          Confirm.textColor = Color.Transparent;
          Decline.color = Color.Transparent;
          Decline.textColor = Color.Transparent;
          PanelBox.color = Color.Transparent;
          PanelBox.textColor = Color.Transparent;
          ShadowBox.color = Color.Transparent;
          Black.color = Color.Transparent;
          counter = 4;
        }
        else
          {
            if ((OverloadProfile) || (ErrDel))
            {
              MaxProfCount = 0;
              ShadowBox.color = Color.Transparent;
              PanelBox.color = Color.Transparent;
              PanelBox.textColor = Color.Transparent;
              Black.color = Color.Transparent;
              ColorTimer.A = 230;
              ErrDel = false;
              OverloadProfile = false;
              ColorTimer.A = 230;
              counter = 4;
            }
            else
            {
              Direction = -1;
              Animated = true;
            }
          }
        
      }

      // Animation that moves all the elements in the gamescreen
      if (Animated)
      {
        bounds.Y += Direction * 35;

        foreach (Button b in (from cb in buttons select cb.b))
        {
          b.bounds.Y += Direction * 35;
        }

        if (bounds.Y > 0 && Direction == 1)
        {
          Animated = false;
          int offset = bounds.Y;
          bounds.Y = 0;

          foreach (Button b in (from cb in buttons select cb.b))
          {
            b.bounds.Y += -Direction * offset;
          }

        }

        if (bounds.Y < savedPos.Y)
        {
          if (flag)
          {
            if (OnNewProfileClicked != null)
              OnNewProfileClicked();
          }
          else
          {
            if (OnBackClicked != null)
              OnBackClicked();
          }
        }
      }

      //Display warning sentences for a short period of time to warn the user if has been reached the maximum number 
      //of profiles or if you try to use the delete button when the list of profiles is empty
      if ((OverloadProfile) || (ErrDel))
      {
        MaxProfCount++;
        if (MaxProfCount > 70)
        {
          MaxProfCount = 0;
          ShadowBox.color = Color.Transparent;
          PanelBox.color = Color.Transparent;
          PanelBox.textColor = Color.Transparent;
          Black.color = Color.Transparent;
          ColorTimer.A = 230;   
          ErrDel = false;
          OverloadProfile = false;
          ColorTimer.A = 230;
          counter = 4;
        }
      }     
      else
      {
        for (int i = 0; i < UserNames.Count; i++)
          SavedProfile[i].color = Color.PaleGreen;
      }

      if (Confirm.textColor == Color.White)
      {
        ShadowBox.color = colorBoxShadow;
        PanelBox.color = colorBox;
        PanelBox.textColor = Color.Red;

        if((OnDelete) && (clickedBtn != -1))
          PanelBox.message = String.Format(Locale.Strings.DeleteProfileRequest, SavedProfile[clickedBtn].message);
        else
          PanelBox.message = Locale.Strings.DeleteAllRequest;

      }

      if (OverloadProfile)
      {
        ShadowBox.color = colorBoxShadow;
        PanelBox.color = colorBox;
        PanelBox.textColor = Color.Red;
        PanelBox.message = Locale.Strings.NewProfileError.Replace("\\n", "\n");
        Black.color = ColorTimer;
        ColorTimer.A--;
      }

      if (ErrDel)
      {
        ShadowBox.color = colorBoxShadow;
        PanelBox.color = colorBox;
        PanelBox.textColor = Color.Red;
        PanelBox.message = Locale.Strings.DeleteProfileError;
      }

     
      base.Update(gameTime);
    }


    public override void Draw(GameTime gameTime)
    {
      base.Draw(gameTime);
      
      spriteBatch.Begin();
      
      spriteBatch.DrawString(Game.Content.Load<SpriteFont>("baveuse1_font"), Locale.Strings.YourProfiles, new Vector2(100, bounds.Y + 10), Color.Black);
      spriteBatch.DrawString(Game.Content.Load<SpriteFont>("baveuse1_font"), Locale.Strings.Info, new Vector2(bounds.Center.X + 200, bounds.Y + 10), Color.Black);
   
      spriteBatch.End();
    }

    public event MenuEvent OnNewProfileClicked;
    public event MenuEvent OnBackClicked;
    public event MenuEvent OnReload;
  }
}
